﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GuiLibrary.Components;
using Microsoft.Xna.Framework;

namespace GuiLibrary.layouts
{
    public class BorderLayout: Layout
    {
        protected int prevPointedElement;

        public BorderLayout(Panel parentPanel, int[] margins, IOnElementSelected onComponentSelected, IOnCancel onCancel, IOnElementPointed onComponentPointed) :
        base(parentPanel, margins, onComponentSelected, onCancel, onComponentPointed)
        { 
        
        }

        public void addComponent(Component component, BorderLocation location) 
        {
            List<Component> components = getComponents();
            for (int i = 0; i < 5; i++)
            {
                if (components.Count <= i)
                    components.Add(i==(int)location ? component : null);
            }
        }

        public override Microsoft.Xna.Framework.Vector2 getComponentSize(Component component)
        {
            return component.getSize();
        }

        public override void changePointedComponent(int nextPosition)
        {
            int aux = pointedElement;
            base.changePointedComponent(nextPosition);
            if (aux != pointedElement) 
                prevPointedElement = aux; //so you don't loose information if it doesn't move
        }

        public override bool canMove(Layout.Cursor cursor)
        {
            if (cursor != Cursor.UP && cursor != Cursor.LEFT && cursor != Cursor.RIGHT && cursor != Cursor.DOWN)
                return true;
            switch ((BorderLocation)pointedElement) { 
                case BorderLocation.UP:
                    if (cursor == Cursor.DOWN)
                        return true;
                    else
                        return false;
                case BorderLocation.LEFT:
                    if (cursor == Cursor.LEFT)
                        return false;
                    else
                        return true;
                case BorderLocation.CENTER:
                    return true;
                case BorderLocation.RIGHT:
                    if(cursor == Cursor.RIGHT)
                        return false;
                    else
                        return true;
                case BorderLocation.DOWN:
                    if (cursor == Cursor.UP)
                        return true;
                    else
                        return false;
            }
            return true;
        }
        public override void moveCursor(Layout.Cursor cursor)
        {
            if (!canMove(cursor))
                return;
            BorderLocation bl = (BorderLocation)pointedElement;
            int nextPosition = pointedElement;
            switch (bl) 
            {
                case BorderLocation.UP:
                    if (cursor == Cursor.DOWN)
                        changePointedComponent(prevPointedElement);
                    break;
                case BorderLocation.LEFT:
                    if (cursor == Cursor.UP)
                        changePointedComponent(pointedElement - 1);
                    else if (cursor == Cursor.RIGHT)
                        changePointedComponent(pointedElement + 1);
                    else if (cursor == Cursor.DOWN)
                        changePointedComponent(pointedElement + 3);
                    break;
                case BorderLocation.CENTER:
                    if (cursor == Cursor.UP)
                        changePointedComponent(pointedElement - 2);
                    else if (cursor == Cursor.LEFT)
                        changePointedComponent(pointedElement - 1);
                    else if (cursor == Cursor.RIGHT)
                        changePointedComponent(pointedElement + 1);
                    else if (cursor == Cursor.DOWN)
                        changePointedComponent(pointedElement + 2);
                    break;
                case BorderLocation.RIGHT:
                    if (cursor == Cursor.UP)
                        changePointedComponent(pointedElement - 3);
                    else if (cursor == Cursor.LEFT)
                        changePointedComponent(pointedElement - 1);
                    else if (cursor == Cursor.DOWN)
                        changePointedComponent(pointedElement + 1);
                    break;
                case BorderLocation.DOWN:
                    if (cursor == Cursor.UP)
                        changePointedComponent(prevPointedElement);
                    break;
            }
            base.moveCursor(cursor);
        }

        public override void eraseComponent(int componentIndex)
        {
            List<Component> components = getComponents();
            if (componentIndex > 4)
                return;
            components[componentIndex] = null;
        }

        public override void refresh()
        {
            Vector2 panelSize = parentPanel.getSize()
                - new Vector2(marginLeft, marginTop) - new Vector2(marginRight, marginDown); //consider margins
            List<Component> components = getComponents();
            Vector2[] sizes = new Vector2[5];
            for (int i = 0; i < 5; i++ )
            {
                if (i >= components.Count)
                    components.Add(null);
                if (components[i] == null)
                    sizes[i] = new Vector2();
                else
                {
                    components[i].refresh();
                    sizes[i] = components[i].getSize();
                }
            }
            //must continue for when there are components at the borders
            Component centerComp = components[(int)BorderLocation.CENTER];
            centerComp.relativePosition = (panelSize - sizes[(int)BorderLocation.CENTER]) / 2;
            centerComp.refresh();
            refreshPointedComponent();
        }

        public enum BorderLocation { 
            UP = 0,
            LEFT = 1,
            CENTER = 2,
            RIGHT = 3,
            DOWN = 4
        }
    }
}
